package com.link.base.base.member.util;

import com.alibaba.fastjson.JSONObject;
import com.link.base.user.model.CoreUser;
import com.link.base.base.common.service.SendSmsService;
import com.link.base.base.email.emailutils.SendMail;
import com.link.core.cllog.LCLogger;
import com.link.core.util.BeanTools;
import com.link.core.util.DateUtil;
import com.link.core.util.RedisUtil;
import com.link.core.util.StringUtils;
import com.link.core.util.redisclient.LinkRedisClient;


import java.text.SimpleDateFormat;
import java.util.*;

/**
 * @author Li Yang
 * 微信/小程序红包工具方法封装类
 */
public class MpPayTools {

    /**
     * @author Li Yang
     * 处理红包和付款的统一入口方法
     */
    public static boolean processEntrance(CoreUser user, String processType) {
        boolean result = false;
        boolean openidOverFrequency = false;
        boolean forgeryFlag = false;
        LinkRedisClient jedis = null;
        MpPayOperationParams mpop = new MpPayOperationParams();
        try {
            jedis = RedisUtil.getJedis();
            //jedis.select(0);
            mpop.setJedis(jedis);
            mpop.setCurrentTimeMillis(System.currentTimeMillis());
            mpop.setUserOpenId(user.getOpenId());
            if (MpPayConstants.FAIL_TO_RECIEVE.equals(processType)) {
                // 处理领取失败
                MpPayTools.processFailToRecieve(mpop);
            } else if (MpPayConstants.OVER_FREQUENCY_REQUEST.equals(processType)) {
                // 处理超频访问（全局处理）
                MpPayTools.processOverFrequencyRequest(mpop);
                // 处理超频访问（对于单个openid）
                openidOverFrequency = MpPayTools.inMpPayRequestBlacklist(mpop);
            } else if (MpPayConstants.FORGERY_REQUEST.equals(processType)) {
                // 先记录伪造请求（全局处理）
                MpPayTools.processForgeryRequest(mpop);
                // 再处理伪造请求（单个openid拉黑）
                forgeryFlag = MpPayTools.inForgeryRequestBlacklist(mpop);
            }
        } catch (Exception e) {
            LCLogger.withException(e);
        } finally {
            RedisUtil.returnResource(jedis);
            RedisUtil.returnResource(mpop.getJedis());
        }
        if (openidOverFrequency || forgeryFlag) {
            result = true;
        }
        return result;
    }

    /**
     * @author Li Yang
     * @param mpop 全局设置，处理领取失败时的通知方法
     */
    public static void processFailToRecieve(MpPayOperationParams mpop) {
        //存入缓存的领取失败list，左进右出
        mpop.getJedis().lpush(MpPayConstants.FAIL_TO_RECIEVE_RECORD_LIST,
                String.valueOf(mpop.getCurrentTimeMillis()));
        String limitTime = mpop.getJedis().hget(MpPayConstants.FAIL_TO_RECIEVE, MpPayConstants.FAIL_TO_RECIEVE_LIMIT_TIME);
        //限制时间默认5分钟
        if (StringUtils.isBlank(limitTime)) {
            limitTime = "5";
        }
        String limitNum = mpop.getJedis().hget(MpPayConstants.FAIL_TO_RECIEVE, MpPayConstants.FAIL_TO_RECIEVE_LIMIT_NUM);
        //默认失败次数为1次
        if (StringUtils.isBlank(limitNum)) {
            limitNum = "1";
        }
        //获取第limitNum次的时间
        String limitNumTime = mpop.getJedis().lindex(MpPayConstants.FAIL_TO_RECIEVE_RECORD_LIST, Long.parseLong(limitNum) - 1);
        //如果取出的对应时间为空，则表示没有超出限制，如果不为空，则需要进一步对比
        if (!StringUtils.isBlank(limitNumTime)) {
            long result = mpop.getCurrentTimeMillis() - Long.parseLong(limitTime) * 60 * 1000 - Long.parseLong(limitNumTime);
            //result小于等于0表示限制次数上限的访问时间是在规定的限制时间之内，即满足发送短信的条件
            if (result <= 0) {
                AlertMsgConfig alertMsgConfig = new AlertMsgConfig();
                //配置短信信息
                alertMsgConfig.setMsgContent1("领取失败频率超出限制");
                alertMsgConfig.setPhones(mpop.getJedis().hget(MpPayConstants.FAIL_TO_RECIEVE, MpPayConstants.FAIL_TO_RECIEVE_ALERT_PHONE_NUMBER));
                String nextFailRecieveAlertTime = mpop.getJedis().hget(MpPayConstants.FAIL_TO_RECIEVE,
                        MpPayConstants.NEXT_FAIL_TO_RECIEVE_ALERT_TIME);
                //获取短信code并设置到参数
                String msgCode = mpop.getJedis().hget(MpPayConstants.FAIL_TO_RECIEVE, MpPayConstants.FAIL_TO_RECIEVE_SMS_CODE);
                alertMsgConfig.setMsgCode(msgCode);
                //设置下次通知时间参数的值
                mpop.setNextAlertTimeKey(MpPayConstants.FAIL_TO_RECIEVE);
                mpop.setNextAlertTimeField(MpPayConstants.NEXT_FAIL_TO_RECIEVE_ALERT_TIME);
                mpop.setNextAlertTimeInterval(mpop.getJedis().hget(MpPayConstants.FAIL_TO_RECIEVE,
                        MpPayConstants.NEXT_FAIL_TO_RECIEVE_ALERT_TIME_INTERVAL));
                if (StringUtils.isBlank(nextFailRecieveAlertTime)) {
                    alertMsgConfig.setNextAlertTime(mpop.getCurrentTimeMillis() -  5 * 60 * 1000);
                } else {
                    alertMsgConfig.setNextAlertTime(Long.parseLong(nextFailRecieveAlertTime));
                }
                //发送预警短信邮件
                MpPayTools.processSendSms(alertMsgConfig, mpop);
            }
        }
        //将过期的领取失败信息写入到持久层，获取list长度
        long listLength = mpop.getJedis().llen(MpPayConstants.FAIL_TO_RECIEVE_RECORD_LIST);
        List<String> oldTimeList = mpop.getJedis().lrange(MpPayConstants.FAIL_TO_RECIEVE_RECORD_LIST, Long.parseLong(limitNum), listLength);
        //将截取到的过期信息写入持久层（未实现）

        //截取缓存中的记录信息，对list进行修剪，去掉过期信息
        mpop.getJedis().ltrim(MpPayConstants.FAIL_TO_RECIEVE_RECORD_LIST, 0, Long.parseLong(limitNum) - 1);
    }

    /**
     * @author Li Yang
     * @param mpop 全局设置，处理超频的领取请求和通知
     */
    public static void processOverFrequencyRequest(MpPayOperationParams mpop) {
        // 缓存访问记录，左进右出
        mpop.getJedis().lpush(MpPayConstants.MP_PAY_REQUEST_RECORD_LIST,
                String.valueOf(mpop.getCurrentTimeMillis()));
        String limitTime = mpop.getJedis().hget(MpPayConstants.OVER_FREQUENCY_REQUEST, MpPayConstants.OVER_FREQUENCY_REQUEST_LIMIT_TIME);
        // 限制时间默认5分钟
        if (StringUtils.isBlank(limitTime)) {
            limitTime = "5";
        }
        String limitNum = mpop.getJedis().hget(MpPayConstants.OVER_FREQUENCY_REQUEST, MpPayConstants.OVER_FREQUENCY_REQUEST_LIMIT_NUM);
        // 默认失败次数为10次
        if (StringUtils.isBlank(limitNum)) {
            limitNum = "10";
        }
        // 获取第limitNum次的时间
        String limitNumTime = mpop.getJedis().lindex(MpPayConstants.MP_PAY_REQUEST_RECORD_LIST, Long.parseLong(limitNum) - 1);
        // 如果取出的对应时间为空，则表示没有超出限制，如果不为空，则需要进一步对比
        if (!StringUtils.isBlank(limitNumTime)) {
            long result = mpop.getCurrentTimeMillis() - Long.parseLong(limitTime) * 60 * 1000 - Long.parseLong(limitNumTime);
            // result小于等于0表示限制次数上限的访问时间是在规定的限制时间之内，即满足发送短信的条件
            if (result <= 0) {
                AlertMsgConfig alertMsgConfig = new AlertMsgConfig();
                //配置短信信息
                // 短信内容
                alertMsgConfig.setMsgContent1("领取请求频率超出限制");
                // 短信号码
                alertMsgConfig.setPhones(mpop.getJedis().hget(MpPayConstants.OVER_FREQUENCY_REQUEST,
                        MpPayConstants.OVER_FREQUENCY_REQUEST_ALERT_PHONE_NUMBER));
                // 下次超频时间
                String nextOverFrequencyAlertTime = mpop.getJedis()
                        .hget(MpPayConstants.OVER_FREQUENCY_REQUEST, MpPayConstants.NEXT_OVER_FREQUENCY_REQUEST_ALERT_TIME);
                // 短信模板id
                String msgCode = mpop.getJedis().hget(MpPayConstants.OVER_FREQUENCY_REQUEST, MpPayConstants.OVER_FREQUENCY_REQUEST_SMS_CODE);
                alertMsgConfig.setMsgCode(msgCode);

                //设置下次通知时间参数的值
                mpop.setNextAlertTimeKey(MpPayConstants.OVER_FREQUENCY_REQUEST);
                mpop.setNextAlertTimeField(MpPayConstants.NEXT_OVER_FREQUENCY_REQUEST_ALERT_TIME);
                mpop.setNextAlertTimeInterval(mpop.getJedis().hget(MpPayConstants.OVER_FREQUENCY_REQUEST,
                        MpPayConstants.NEXT_OVER_FREQUENCY_REQUEST_ALERT_TIME_INTERVAL));
                // 如果redis中没有超频时间,则设置为当前时间5分钟前
                if (StringUtils.isBlank(nextOverFrequencyAlertTime)) {
                    alertMsgConfig.setNextAlertTime(mpop.getCurrentTimeMillis() - 5 * 60 * 1000);
                } else {
                    alertMsgConfig.setNextAlertTime(Long.parseLong(nextOverFrequencyAlertTime));
                }
                //发送预警短信邮件
                MpPayTools.processSendSms(alertMsgConfig, mpop);
            }
        }
        //将过期的领取失败信息写入到持久层，获取list长度
        long listLength = mpop.getJedis().llen(MpPayConstants.MP_PAY_REQUEST_RECORD_LIST);
        List<String> oldTimeList = mpop.getJedis().lrange(MpPayConstants.MP_PAY_REQUEST_RECORD_LIST, Long.parseLong(limitNum), listLength);
        //将截取到的过期信息写入持久层（未实现）

        //截取缓存中的记录信息，对list进行修剪，去掉过期信息
        mpop.getJedis().ltrim(MpPayConstants.MP_PAY_REQUEST_RECORD_LIST, 0, Long.parseLong(limitNum) - 1);
    }

    /**
     * @author Li Yang
     * @param mpop 全局设置，处理伪造请求和通知
     */
    public static void processForgeryRequest(MpPayOperationParams mpop) {
        //缓存访问记录，左进右出
        mpop.getJedis().lpush(MpPayConstants.FORGERY_REQUEST_RECORD_LIST,
                String.valueOf(mpop.getCurrentTimeMillis()));
        String limitTime = mpop.getJedis().hget(MpPayConstants.FORGERY_REQUEST, MpPayConstants.FORGERY_REQUEST_LIMIT_TIME);
        //限制时间默认5分钟
        if (StringUtils.isBlank(limitTime)) {
            limitTime = "5";
        }
        String limitNum = mpop.getJedis().hget(MpPayConstants.FORGERY_REQUEST, MpPayConstants.FORGERY_REQUEST_LIMIT_NUM);
        //默认失败次数为100次
        if (StringUtils.isBlank(limitNum)) {
            limitNum = "100";
        }
        //获取第limitNum次的时间
        String limitNumTime = mpop.getJedis().lindex(MpPayConstants.FORGERY_REQUEST_RECORD_LIST, Long.parseLong(limitNum) - 1);
        //如果取出的对应时间为空，则表示没有超出限制，如果不为空，则需要进一步对比
        if (!StringUtils.isBlank(limitNumTime)) {
            long result = mpop.getCurrentTimeMillis() - Long.parseLong(limitTime) * 60 * 1000 - Long.parseLong(limitNumTime);
            //result小于等于0表示限制次数上限的访问时间是在规定的限制时间之内，即满足发送短信的条件
            if (result <= 0) {
                AlertMsgConfig alertMsgConfig = new AlertMsgConfig();
                //配置短信信息
                alertMsgConfig.setMsgContent1("伪造请求频率超出限制");
                alertMsgConfig.setPhones(mpop.getJedis().hget(MpPayConstants.FORGERY_REQUEST, MpPayConstants.FORGERY_REQUEST_ALERT_PHONE_NUMBER));
                String nextForgeryAlertTime = mpop.getJedis()
                        .hget(MpPayConstants.FORGERY_REQUEST, MpPayConstants.NEXT_FORGERY_REQUEST_ALERT_TIME);
                //获取短信code并设置到参数
                String msgCode = mpop.getJedis().hget(MpPayConstants.FORGERY_REQUEST, MpPayConstants.FORGERY_REQUEST_SMS_CODE);
                alertMsgConfig.setMsgCode(msgCode);
                //设置下次通知时间参数的值
                mpop.setNextAlertTimeKey(MpPayConstants.FORGERY_REQUEST);
                mpop.setNextAlertTimeField(MpPayConstants.NEXT_FORGERY_REQUEST_ALERT_TIME);
                mpop.setNextAlertTimeInterval(mpop.getJedis().hget(MpPayConstants.FORGERY_REQUEST,
                        MpPayConstants.NEXT_FORGERY_REQUEST_ALERT_TIME_INTERVAL));
                if (StringUtils.isBlank(nextForgeryAlertTime)) {
                    alertMsgConfig.setNextAlertTime(mpop.getCurrentTimeMillis() - 5 * 60 * 1000);
                } else {
                    alertMsgConfig.setNextAlertTime(Long.parseLong(nextForgeryAlertTime));
                }
                //发送预警短信邮件
                MpPayTools.processSendSms(alertMsgConfig, mpop);
            }
        }
        //将过期的领取失败信息写入到持久层，获取list长度
        long listLength = mpop.getJedis().llen(MpPayConstants.FORGERY_REQUEST_RECORD_LIST);
        List<String> oldTimeList = mpop.getJedis().lrange(MpPayConstants.FORGERY_REQUEST_RECORD_LIST, Long.parseLong(limitNum), listLength);
        //将截取到的过期信息写入持久层（未实现）

        //截取缓存中的记录信息，对list进行修剪，去掉过期信息
        mpop.getJedis().ltrim(MpPayConstants.FORGERY_REQUEST_RECORD_LIST, 0, Long.parseLong(limitNum) - 1);
    }

    /**
     * @author Li Yang
     * @param alertMsgConfig 处理通知消息 （未完成）
     */
    public static void processSendSms(AlertMsgConfig alertMsgConfig, MpPayOperationParams mpop) {
        try {
            // 如果当前时间大于下次发出预警时间，就发预警短信
            if (alertMsgConfig.getNextAlertTime() < mpop.getCurrentTimeMillis()) {
                //重置下次通知时间
                String intervalStr = mpop.getNextAlertTimeInterval();
                if (StringUtils.isBlank(intervalStr)) {
                    intervalStr = "10";
                }
                long interval = mpop.getCurrentTimeMillis() + Long.parseLong(intervalStr) * 60 * 1000;
                mpop.getJedis().hset(mpop.getNextAlertTimeKey(), mpop.getNextAlertTimeField(), String.valueOf(interval));
                //如果通知的手机号不为空
                if (!StringUtils.isBlank(alertMsgConfig.getPhones())) {
                    SendSmsService sendSmsService = (SendSmsService) BeanTools.getBean(SendSmsService.class);
                    List<String> phoneList = JSONObject.parseArray("[" + alertMsgConfig.getPhones() + "]", String.class);
                    String msgCode = alertMsgConfig.getMsgCode();
                    //发送短信
                    String msgContentJson = "{\"content\":\"" + alertMsgConfig.getMsgContent1() + "\"}";
                    sendSmsService.tencentMultiSendSms(msgCode, msgContentJson, null, phoneList);
                }
                //如果通知的邮箱不为空
                if (!StringUtils.isBlank(alertMsgConfig.getSendToEmails())) {
                    Map<String, String> emailParams = new HashMap<>(8);
                    String fromAddr = "237649071@qq.com";
                    //接收人的帐号，多个以","号隔开
                    emailParams.put("to", alertMsgConfig.getSendToEmails());
                    //邮件主题
                    emailParams.put("subject", alertMsgConfig.getEmailTitle());
                    //邮件内容
                    emailParams.put("body", alertMsgConfig.getEmailContents());
                    emailParams.put("from", fromAddr);
                    //创建实例
                    SendMail sm = new SendMail(emailParams, new ArrayList<String>(), null);
                    //执行发送
                    sm.sendQqMail();
                }
            }
        } catch (Exception e) {
            LCLogger.withException(e);
        }
    }

    /**
     * 判断并处理openid是否在伪造（异常）请求黑名单
     *
     * @param mpop
     * @return
     */
    public static boolean inForgeryRequestBlacklist(MpPayOperationParams mpop) {
        boolean flag = false;
        String blacklistKey = MpPayConstants.RED_ENVELOPES_BLACK_LIST_KEY + mpop.getUserOpenId();
        //得到配置中允许的最大伪造请求次数
        String maxForgeryTime = mpop.getJedis().hget(MpPayConstants.RED_ENVELOPES_CONFIG_KEY,
                MpPayConstants.RED_ENVELOPES_FORGERY_REQUEST_NUM);
        //如果取不到就默认2次
        if (StringUtils.isBlank(maxForgeryTime)) {
            maxForgeryTime = "2";
        }
        String stopTimeInterval = mpop.getJedis().hget(MpPayConstants.RED_ENVELOPES_CONFIG_KEY,
                MpPayConstants.RED_ENVELOPES_FORGERY_REQUEST_TIME_INTERVAL);
        //如果取不到就默认拉黑24小时，这里的时间间隔（小时）必须是整数
        if (StringUtils.isBlank(stopTimeInterval)) {
            stopTimeInterval = "24";
        }
        //根据key，选择一个对应的jedis库
        //mpop.getJedis().select(VisitStatisticsTools.getDbIndex(blacklistKey));
        long listLength = mpop.getJedis().llen(blacklistKey);
        if (listLength + 1 < Long.parseLong(maxForgeryTime)) {
            //如果当前取出的累计伪造访问次数+本次访问 小于 设置的值，则往记录里面+1条记录
            mpop.getJedis().lpush(blacklistKey, String.valueOf(mpop.getCurrentTimeMillis()));
        } else if (listLength + 1 == Long.parseLong(maxForgeryTime)) {
            //如果当前取出的累计伪造访问次数+本次访问 等于 设置的值，则往记录里面+1条记录并设置一个黑名单过期时间，返回值设为true
            flag = true;
            mpop.getJedis().lpush(blacklistKey, String.valueOf(mpop.getCurrentTimeMillis()));
            //设置拉黑时长
            mpop.getJedis().expire(blacklistKey, 60 * 60 * Integer.parseInt(stopTimeInterval));
        } else {
            //如果当前取出的累计伪造访问次数+本次访问 大于 设置的值，则直接返回值设为true，表示当前已被拉黑
            flag = true;
        }
        //重置jedis库
        //mpop.getJedis().select(0);
        return flag;
    }

    /**
     * 判断openid是否有超频付款请求情况
     *
     * @param mpop
     * @return
     */
    public static boolean inMpPayRequestBlacklist(MpPayOperationParams mpop) {
        boolean flag = false;
        //声明每一个openid付款访问记录的key
        String blacklistKey = MpPayConstants.MP_PAY_BLACK_LIST_KEY + mpop.getUserOpenId();
        //根据key，选择一个对应的jedis库
//        System.out.println(VisitStatisticsTools.getDbIndex(blacklistKey));
        //mpop.getJedis().select(VisitStatisticsTools.getDbIndex(blacklistKey));
        String stopTimeInterval = mpop.getJedis().hget(MpPayConstants.MP_PAY_CONFIG_KEY,
                MpPayConstants.MP_PAY_OPENID_REQUEST_TIME_INTERVAL);
        //如果取不到就默认拉黑24小时，这里的时间间隔（小时）必须是整数
        if (StringUtils.isBlank(stopTimeInterval)) {
            stopTimeInterval = "24";
        }
        //查看该openid是否在黑名单，并得到拉黑的时间戳
        String blackListOpenidMillis = mpop.getJedis().hget(MpPayConstants.MP_PAY_BLACK_LIST_MAP_KEY,
                mpop.getUserOpenId());
        if (!StringUtils.isBlank(blackListOpenidMillis)) {
            //如果在黑名单，则对拉黑时间进行匹配
            long inBlackList = mpop.getCurrentTimeMillis() - Long.parseLong(blackListOpenidMillis);
            if (inBlackList <= 0) {
                //说明此时还在拉黑的过程中
                return true;
            } else {
                //超出了拉黑时间，将openid从黑名单中移除
                mpop.getJedis().hdel(MpPayConstants.MP_PAY_BLACK_LIST_MAP_KEY,
                        mpop.getUserOpenId());
            }
        }
        //得到配置中单位时间内允许的最大请求次数
        String requestLimitNum = mpop.getJedis().hget(MpPayConstants.MP_PAY_CONFIG_KEY,
                MpPayConstants.MP_PAY_OPENID_LIMIT_NUM);
        //如果取不到就默认10次
        if (StringUtils.isBlank(requestLimitNum)) {
            requestLimitNum = "10";
        }
        String requestLimitTime = mpop.getJedis().hget(MpPayConstants.MP_PAY_CONFIG_KEY,
                MpPayConstants.MP_PAY_OPENID_LIMIT_TIME);
        //如果取不到就默认频率的时间为5分钟
        if (StringUtils.isBlank(requestLimitTime)) {
            requestLimitTime = "5";
        }
        long listLength = mpop.getJedis().llen(blacklistKey);
        if (listLength + 1 < Long.parseLong(requestLimitNum)) {
            //如果当前取出的累计伪造访问次数+本次访问 小于 设置的值，则往记录里面+1条记录
            mpop.getJedis().lpush(blacklistKey, String.valueOf(mpop.getCurrentTimeMillis()));
        } else {
            //将当前访问记录添加至记录列表
            mpop.getJedis().lpush(blacklistKey, String.valueOf(mpop.getCurrentTimeMillis()));
            //如果当前取出的累计伪造访问次数+本次访问 大于等于 设置的值时，取第requestLimitNum个时间
            String limitNumTime = mpop.getJedis().lindex(blacklistKey, Long.parseLong(requestLimitNum) - 1);
            if (!StringUtils.isBlank(limitNumTime)) {
                long result = mpop.getCurrentTimeMillis() - Long.parseLong(requestLimitTime) * 60 * 1000 - Long.parseLong(limitNumTime);
                //result小于等于0表示限制次数上限的访问时间是在规定的限制时间之内，即满足拉黑条件
                if (result <= 0) {
                    flag = true;
                    //将该openid添加至黑名单，并设置解除黑明单的时间
                    mpop.getJedis().hset(MpPayConstants.MP_PAY_BLACK_LIST_MAP_KEY,
                            mpop.getUserOpenId(),
                            String.valueOf(Long.parseLong(stopTimeInterval) * 60 * 60 * 1000 + mpop.getCurrentTimeMillis()));
                }
                //修剪记录列表
                mpop.getJedis().ltrim(MpPayConstants.MP_PAY_BLACK_LIST_KEY, 0, Long.parseLong(requestLimitNum) - 1);
            }
        }
        //重置jedis库
       // mpop.getJedis().select(0);
        return flag;
    }

    /**
     * 校验单人单日付款总金额
     *
     * @author LiQun
     * @date 2019/2/25 20:56
     */
    public static boolean checkMpSingleDayUserPayAmount(CoreUser user) {
        boolean flag = false;
        LinkRedisClient jedis = RedisUtil.getJedis();
        try {
            String dayLimitMaxPayAmount = jedis.hget(MpPayConstants.MP_PAY_CONFIG_KEY, MpPayConstants.DAY_LIMIT_MAX_PAY_AMOUNT);
            if (StringUtils.isBlank(dayLimitMaxPayAmount)) {
                // 如果为空,默认值为5000
                dayLimitMaxPayAmount = "5000";
            }
            String todaySumAmount = jedis.hget("DAY_LIMIT_MAX_PAY_AMOUNT_" + user.getOpenId(), "todaySumAmount");
            String lastPayTimeMillis = jedis.hget("DAY_LIMIT_MAX_PAY_AMOUNT_" + user.getOpenId(), "lastPayTimeMillis");
            if (StringUtils.isBlank(todaySumAmount)) {
                todaySumAmount = "0";
            }
            if (StringUtils.isBlank(lastPayTimeMillis)) {
                lastPayTimeMillis = String.valueOf(System.currentTimeMillis());
            }
            // 在今天范围内,且付款总金额已经超过设置金额,进行短信预警提示
            flag = DateUtil.isToday(new Date(Long.parseLong(lastPayTimeMillis)))
                    && Double.parseDouble(dayLimitMaxPayAmount) < Double.parseDouble(todaySumAmount);
        } catch (Exception e) {
            LCLogger.withException(e);
        } finally {
            RedisUtil.returnResource(jedis);
        }
        return flag;
    }

    /**
     * 校验单人单日付款总次数
     *
     * @author LiQun
     * @date 2019/2/25 20:56
     */
    public static boolean checkMpSingleDayUserPayNum(CoreUser user) {
        boolean flag = false;
        LinkRedisClient jedis = RedisUtil.getJedis();
        try {
            String dayLimitMaxPayNum = jedis.hget(MpPayConstants.MP_PAY_CONFIG_KEY, MpPayConstants.DAY_LIMIT_MAX_PAY_NUM);
            if (StringUtils.isBlank(dayLimitMaxPayNum)) {
                // 如果为空,默认值为5000
                dayLimitMaxPayNum = "10";
            }
            String todaySumNum = jedis.hget("MP_SINGLE_DAY_PAY_NUM_" + user.getOpenId(), "todaySumNum");
            String lastPayTimeMillis = jedis.hget("MP_SINGLE_DAY_PAY_NUM_" + user.getOpenId(), "lastPayTimeMillis");
            if (StringUtils.isBlank(todaySumNum)) {
                todaySumNum = "0";
            }
            if (StringUtils.isBlank(lastPayTimeMillis)) {
                lastPayTimeMillis = String.valueOf(System.currentTimeMillis());
            }
            // 在今天范围内,且付款总金额已经超过设置金额,进行短信预警提示
            flag = DateUtil.isToday(new Date(Long.parseLong(lastPayTimeMillis)))
                    && Integer.parseInt(dayLimitMaxPayNum) < Integer.parseInt(todaySumNum);
        } catch (Exception e) {
            LCLogger.withException(e);
        } finally {
            RedisUtil.returnResource(jedis);
        }
        return flag;
    }

    /**
     * 校验单日总付款金额
     *
     * @author LiQun
     * @date 2019/2/19
     */
    public static boolean checkMpSingleDayPayAmount(CoreUser user) {
        boolean flag = false;
        LinkRedisClient jedis = RedisUtil.getJedis();
        MpPayOperationParams mpop = new MpPayOperationParams();
        try {
            String dayAlertMaxPayAmount = jedis.hget(MpPayConstants.MP_PAY_CONFIG_KEY, MpPayConstants.DAY_ALERT_MAX_PAY);
            if (StringUtils.isBlank(dayAlertMaxPayAmount)) {
                // 如果为空,默认值为5000
                dayAlertMaxPayAmount = "5000";
            }
            String todaySumAmount = jedis.hget("MP_SINGLE_DAY_PAY_AMOUNT", "todaySumAmount");
            String lastPayTimeMillis = jedis.hget("MP_SINGLE_DAY_PAY_AMOUNT", "lastPayTimeMillis");
            if (StringUtils.isBlank(todaySumAmount)) {
                todaySumAmount = "0";
            }
            if (StringUtils.isBlank(lastPayTimeMillis)) {
                lastPayTimeMillis = String.valueOf(System.currentTimeMillis());
            }
            // 在今天范围内,且付款总金额已经超过设置金额,进行短信预警提示
            if (DateUtil.isToday(new Date(Long.parseLong(lastPayTimeMillis)))
                    && Double.parseDouble(dayAlertMaxPayAmount) < Double.parseDouble(todaySumAmount)) {
                flag = true;
                // 进行短信预警提示
                AlertMsgConfig alertMsgConfig = new AlertMsgConfig();
                mpop.setJedis(jedis);
                mpop.setCurrentTimeMillis(System.currentTimeMillis());
                mpop.setUserOpenId(user.getOpenId());

                // 配置短信信息
                String msgContent = "红包领取金额超今日总限额";
                alertMsgConfig.setMsgContent1(msgContent);
                // 手机号
                alertMsgConfig.setPhones(jedis.hget(MpPayConstants.MP_PAY_CONFIG_KEY,
                        MpPayConstants.DAY_ALERT_MAX_PHONE));
                // 下次发送预警时间
                String nextOverFrequencyAlertTime = mpop.getJedis()
                        .hget(MpPayConstants.MP_PAY_CONFIG_KEY, MpPayConstants.NEXT_OVER_FREQUENCY_REQUEST_ALERT_TIME);
                //获取短信templateId并设置到参数
                String msgCode = jedis.hget(MpPayConstants.MP_PAY_CONFIG_KEY, MpPayConstants.DAY_ALERT_MAX_MSG_TEMPLATE);
                alertMsgConfig.setMsgCode(msgCode);
                //设置下次通知时间参数的值
                mpop.setNextAlertTimeKey(MpPayConstants.MP_PAY_CONFIG_KEY);
                mpop.setNextAlertTimeField(MpPayConstants.NEXT_OVER_FREQUENCY_REQUEST_ALERT_TIME);
                mpop.setNextAlertTimeInterval(mpop.getJedis().hget(MpPayConstants.MP_PAY_CONFIG_KEY,
                        MpPayConstants.NEXT_OVER_FREQUENCY_REQUEST_ALERT_TIME_INTERVAL));
                if (StringUtils.isBlank(nextOverFrequencyAlertTime)) {
                    alertMsgConfig.setNextAlertTime(mpop.getCurrentTimeMillis() - 5 * 60 * 1000);
                } else {
                    alertMsgConfig.setNextAlertTime(Long.parseLong(nextOverFrequencyAlertTime));
                }
                //发送预警短信邮件
                MpPayTools.processSendSms(alertMsgConfig, mpop);
            }
        } catch (Exception e) {
            LCLogger.withException(e);
        } finally {
            RedisUtil.returnResource(jedis);
        }
        return flag;
    }

    /**
     * 设置单日领取总金额
     *
     * @author LiQun
     * @date 2019/2/19
     * @param amount   最新一次领取的金额
     * @param redisKey redis键
     */
    public static void setMpMpSingleDayPayAmount(Double amount, String redisKey) {
        LinkRedisClient jedis = RedisUtil.getJedis();
        try {
            // 金额进行累加
            jedis.hincrByFloat(redisKey, "todaySumAmount", amount);
            // 设置最新时间
            jedis.hset(redisKey, "lastPayTimeMillis", String.valueOf(System.currentTimeMillis()));
            // 设置redis key过期时间
            SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd");
            String nowDateStr = simpleDateFormat.format(new Date());
            nowDateStr += " 23:59:59";
            simpleDateFormat.applyPattern("yyyy-MM-dd HH:mm:ss");
            Date nowDate = simpleDateFormat.parse(nowDateStr);
            // 获取当前时间距离"今日23:59:59"时间差,作为超时时间
            jedis.pexpire(redisKey, nowDate.getTime() - System.currentTimeMillis());
        } catch (Exception e) {
            LCLogger.withException(e);
        } finally {
            RedisUtil.returnResource(jedis);
        }
    }

    /**
     * 设置单日领取总金额
     *
     * @author LiQun
     * @date 2019/2/19
     * @param redisKey redis键
     */
    public static void setMpMpSingleDayPayNum(String redisKey) {
        LinkRedisClient jedis = RedisUtil.getJedis();
        try {
            // 数量进行自增1
            jedis.hincrBy(redisKey, "todaySumNum", 1);
            // 设置最新时间
            jedis.hset(redisKey, "lastPayTimeMillis", String.valueOf(System.currentTimeMillis()));
            // 设置redis key过期时间
            SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd");
            String nowDateStr = simpleDateFormat.format(new Date());
            nowDateStr += " 23:59:59";
            simpleDateFormat.applyPattern("yyyy-MM-dd HH:mm:ss");
            Date nowDate = simpleDateFormat.parse(nowDateStr);
            // 获取当前时间距离"今日23:59:59"时间差,作为超时时间
            jedis.pexpire(redisKey, nowDate.getTime() - System.currentTimeMillis());
        } catch (Exception e) {
            LCLogger.withException(e);
        } finally {
            RedisUtil.returnResource(jedis);
        }
    }

    /**
     * 校验单个红包最大限额
     *
     * @author LiQun
     * @date 2019/2/25 20:48
     */
    public static boolean checkMaxDrawAmount(Double money) {
        LinkRedisClient jedis = RedisUtil.getJedis();
        boolean flag = false;
        try {
            // 从redis中获取金额
            String drawMaxAmountStr = jedis.hget(MpPayConstants.RED_ENVELOPES_CONFIG_KEY, MpPayConstants.RED_ENVELOPES_MAX_PRICE);
            if (StringUtils.isBlank(drawMaxAmountStr)) {
                drawMaxAmountStr = "4999";
            }
            Double drawMaxAmount = Double.parseDouble(drawMaxAmountStr);
            if (drawMaxAmount < money) {
                flag = true;
            }
        } catch (Exception e) {
            LCLogger.withException(e);
        } finally {
            RedisUtil.returnResource(jedis);
        }

        return flag;
    }
}
